package pl.streamsoft.currencyApp.services;

import java.net.URL;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import pl.streamsoft.currencyApp.model.Currency;
import pl.streamsoft.currencyApp.parser.ICurrencyParser;
import pl.streamsoft.currencyApp.stream.InputStreamReader;

public class CurrencyService implements ICurrencyService {
	
	private ICurrencyParser xmlParser;
	
	public CurrencyService(ICurrencyParser parser) {
		this.xmlParser = parser;
	}

	@Override
	public List<Currency> getListOfCurrenciesFromDate(Date date, char currencyCodeStart) throws RuntimeException {
		String date2 = date.toLocaleString().substring(0, 10);
		date2 = date2.substring(2, date2.length());
		date2 = date2.replace('-', ' ');
		date2 = date2.replaceAll("\\s","");
		
		List<Currency> listOfCurrencies = new ArrayList<Currency>();
		//getting list of file names where currency page code is stored
		String[] listOfFileNamesOfCurrencyXML = getFileWithFileNamesOfCurrencyXML();
		//getting end of url where we can find page with currencies
		String endOfURL = findFileNameByDate(listOfFileNamesOfCurrencyXML, date2, currencyCodeStart);
		//getting list of currencies from date
		try {
			listOfCurrencies = this.xmlParser.getListOfCurrenciesFromStringFile(new InputStreamReader(new URL("http://www.nbp.pl/kursy/xml/"+endOfURL+".xml").openStream(), "ISO-8859-2").getFile());
		} 
		catch (Exception e) {
			throw new RuntimeException("Can't get currencies from nbp.pl by date:"+date.toLocaleString()+"!");
		}
		
		return listOfCurrencies;
	}
	
	private String[] getFileWithFileNamesOfCurrencyXML(){
		try {
			String file = new InputStreamReader(new URL("http://www.nbp.pl/kursy/xml/dir.txt").openStream(), "ISO-8859-2").getFile();
			String[] listOfFileNamesOfCurrencyXML = file.split("\r\n");
			return listOfFileNamesOfCurrencyXML;
		} 
		catch (Exception e) {
			e.printStackTrace();
		}
		
		return null;
	}
	
	private String findFileNameByDate(String[] daysSet, String day, char currencyCodeStart){

		//boolean res = tekst.matches(".*"+day);
		int newDay = Integer.parseInt(day);
        int startIndex = 0;
        int endIndex = daysSet.length - 1;
        int actualyIndex;

        while (true) {
            actualyIndex = ((endIndex - startIndex) / 2) + startIndex;
            int cutted = Integer.parseInt(daysSet[actualyIndex].substring(5, 11));
            
            if(day.equals(cutted==5?String.valueOf("0"+cutted): String.valueOf(cutted)) || cutted+2==Integer.parseInt(day) || cutted+1==Integer.parseInt(day)){
                	//petla w 2 strony ktora sprawdza a
                	
                	boolean yes = true;
                	boolean reverse = false;
                	
                	while(yes){
                		String res =  daysSet[actualyIndex].toString();
                		
                			if(res.charAt(0)== currencyCodeStart){
        	            		yes = false;
        	            		return res;
        	            	}
        	            	else{
        	            		if(cutted == Integer.parseInt(res.substring(5, 11)) && !reverse){
            	            		actualyIndex++;
            	            		res = daysSet[actualyIndex].toString();
        	            		}
        	            		else{
        	            			reverse = true;
        	            			actualyIndex--;
        	            		}
        	            	}
                	}
            }
            
            if(cutted<newDay){
            	startIndex = actualyIndex;
            	continue;
            }
            
            if(cutted>newDay){
            	endIndex = actualyIndex;
            	continue;
            }
        }
    }
}
